package com.moon.common.utils.hql;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import com.moon.common.types.AndOrType;
import com.moon.common.types.QueryTemplate;


@SuppressWarnings("unchecked")
public class QueryUtils {
	
	public static String bulidQuery(Class clazz,Map filterParams){
		Set<Map.Entry<String,Object>> set = filterParams.entrySet();
		int count=0;
		String query = "from "+clazz.getSimpleName();
		for(Map.Entry<String, Object> entry:set){
			String key = entry.getKey();
			String[] filters = splitFilter(key);
			String matchType = filters[0];
			String andOrType = filters[2];
			String queryName = filters[3];
			if(count==0){
				query +=" where "+bulidFirstHQL(matchType,queryName);
			}else{
				query +=bulidHQL(matchType,queryName,andOrType);
			}
			count++;
		}
		return query;
	}
	
	public static Map bulidParams(Map filterParams){
		Set<Map.Entry<String,Object>> set = filterParams.entrySet();
		Map<String,Object> params = new HashMap<String,Object>(); 
		for(Map.Entry<String, Object> entry:set){
			String key = entry.getKey();
			Object value = entry.getValue();
			String[] filters = splitFilter(key);
			String clazzType = filters[1];
			String queryName = filters[3];
			queryName=queryName.replace(".", "");
			value = getRealValue(clazzType,(String) value);
			params.put(queryName, value);
		}
		return params;
	}
	
	private static Object getRealValue(String clazzType,String value) {
		Object realValue = null;
		try {
			switch (clazzType.toUpperCase().charAt(0)) {
			case 'S':
				realValue = String.valueOf(value);
				break;
			case 'I':
				realValue = Integer.valueOf(Integer.parseInt(value));
				break;
			case 'L':
				realValue = Long.valueOf(value);
				break;
			case 'T':
				String formatDate = "yyyy-MM-dd HH:mm:ss";
				SimpleDateFormat sdf = new SimpleDateFormat(formatDate);
				realValue = sdf.parse(value);
				break;
			case 'B':
				realValue = Boolean.valueOf(value);
				break;
			case 'D':
				DecimalFormat df=new DecimalFormat("#.##");
				realValue =df.format(Double.valueOf(value));
				break;
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return realValue;
	}

	private static String bulidFirstHQL(String matchType,String queryName) {
		String query = QueryTemplate.valueOf(matchType).getDesc();
		String paramName=queryName.replace(".", "");
		query = query.replace("C", queryName);
		query = query.replace("P",paramName);
		return query;
	}	
	
	private static String bulidHQL(String matchType,String queryName, String andOrType) {
		String query =AndOrType.valueOf(andOrType).getDesc()+ QueryTemplate.valueOf(matchType).getDesc();
		String paramName=queryName.replace(".", "");
		query = query.replace("C", queryName);
		query = query.replace("P",paramName);
		return query;
	}
	
	private static String[] splitFilter(String filter){
		filter = filter.replace("~", ".");
		String[] filters = filter.split("_");
		return filters;
	}
	
	/**
	 * 过滤request中前缀为 prefix 的请求参数，
	 * 返回request中值不为空的参数和值
	 * @param request HttpServletRequest 
	 * @param prefix String 过滤前缀 eg：'params_a_b_c'
	 * @return Map Key = String ; Value = Object ;
	 * 		 	   Key a_b_c
	 */
	public static Map getParametersStartWithPrefix(HttpServletRequest request, String prefix) {
	    Enumeration paramNames = request.getParameterNames();
	    Map params = new TreeMap();
	    while ((paramNames != null) && (paramNames.hasMoreElements())){
	    	String paramName = (String)paramNames.nextElement();
	    	if(paramName.startsWith(prefix)){
	    		String[] values = request.getParameterValues(paramName);
	    		if((values != null) && (values.length > 0) 
	    				&& values[0]!=null && values[0].length()>0){
	    			String unprefixed = paramName.substring(prefix.length());
	    			params.put(unprefixed, values[0]);
	    		}
	    	}
	    }
	    return params;
	}
	
	public static void main(String[] args) {
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("EQ_L_A_id", "11");
		params.put("EQ_S_A_str", "tester");
		params.put("EQ_D_A_num", "15255.31022");
		params.put("EQ_B_A_bool", "false");
		params.put("EQ_I_A_inte", "100");
		params.put("EQ_T_A_timee", "2005-01-09 23:08:09");
		System.out.println(bulidQuery(Object.class,params));
		bulidParams(params);
		System.out.println();
	}
	
}
